home *** CD-ROM | disk | FTP | other *** search
/ The Complete Utilities To…ka 501 Killer Utilities! / 501 Killer Utilities! (Macworld July 1995).cdr / Programming / Mercutio v1.2 - 2⁄19⁄95 / Sample Code / Mercutio Demo App.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-19  |  11.1 KB  |  534 lines  |  [TEXT/MMCC]

  1. /****************************************************************
  2.  
  3.     Test program for Mercutio MDEF 1.2
  4.     
  5.     by Ramon M. Felciano, Digital Alchemy
  6.     © 1992-1994, All Rights Reserved
  7.     
  8.     
  9. *****************************************************************/
  10.  
  11. #include "Mercutio API.h"
  12.  
  13. MenuHandle    appleMenu, fileMenu, editMenu, modifiersMenu,
  14.             iconsMenu, nonPrintingMenu, callbackMenu, colorMenu;
  15. MenuHandle    ourPopupMenu;
  16.  
  17. enum    {
  18.     appleMenuID = 300,
  19.     fileMenuID,
  20.     editMenuID,
  21.     modifiersMenuID,
  22.     iconsMenuID,
  23.     nonPrintingMenuID,
  24.     callbackMenuID,
  25.     colorMenuID
  26.     };
  27.  
  28. enum    {
  29.     ourPopupMenuID = 1
  30.     };
  31.  
  32. enum    {
  33.     popupDialogItem = 1,
  34.     separatorItem,
  35.     quitItem
  36.     };
  37.     
  38.     
  39. enum    {
  40.     addFolderIconID = 262,
  41.     addFoldersIconID,
  42.     addFileIconID,
  43.     addFilesIconID
  44.     };
  45.  
  46. pascal    void MyGetItemInfo (short menuID, short previousModifiers, RichItemData *itemData);
  47.  
  48. /****
  49.  * InitMacintosh()
  50.  *
  51.  * Initialize all the managers & memory
  52.  *
  53.  ****/
  54.  
  55. void InitMacintosh(void);
  56. void InitMacintosh(void)
  57.  
  58. {
  59.     MaxApplZone();
  60.     
  61.     InitGraf(&qd.thePort);
  62.     InitFonts();
  63.     FlushEvents(everyEvent, 0);
  64.     InitWindows();
  65.     InitMenus();
  66.     TEInit();
  67.     InitDialogs(0L);
  68.     InitCursor();
  69.  
  70. }
  71. /* end InitMacintosh */
  72.  
  73.  
  74. /****
  75.  * SetUpMenus()
  76.  *
  77.  *    Set up the menus. Normally, we’d use a resource file, but
  78.  *    for this example we’ll supply “hardwired” strings.
  79.  *
  80.  ****/
  81.  
  82. void SetUpMenus(void);
  83. void SetUpMenus(void)
  84.  
  85. {
  86.     MenuPrefsRec    prefs;
  87.     
  88.     InsertMenu(appleMenu = GetMenu(appleMenuID), 0);
  89.     InsertMenu(fileMenu = GetMenu(fileMenuID), 0);
  90.     InsertMenu(editMenu = GetMenu(editMenuID), 0);
  91.     InsertMenu(modifiersMenu = GetMenu(modifiersMenuID), 0);
  92.     InsertMenu(iconsMenu = GetMenu(iconsMenuID), 0);
  93.     InsertMenu(nonPrintingMenu = GetMenu(nonPrintingMenuID), 0);
  94.     InsertMenu(callbackMenu = GetMenu(callbackMenuID), 0);
  95.     InsertMenu(colorMenu = GetMenu(colorMenuID), 0);
  96.     
  97.     InsertMenu(ourPopupMenu = GetMenu(ourPopupMenuID), -1);
  98.     /*
  99.     **    In addition to the condense & extend bits, lets interpret shadow as the controlKey,
  100.     **    and outline as the callback flag.
  101.     */
  102.  
  103.     /*
  104.     
  105.     *** Setup the preferences for our menus *** 
  106.     
  107.     This is where we determine which style bits are mapped to 
  108.     MDEF features. Most of the menus use Mercutio's default 
  109.     settings. These menus are the exceptions. 
  110.     
  111.     Feel free to play with these settings and see how
  112.     the menus are affected.
  113.     
  114.     Note that we could have stored all this information in an
  115.     'Xmnu' resource with the same ID as the menu, and avoided 
  116.     the hassle of setting these preferences programmatically. 
  117.     We do it this way to demonstrate the various features of
  118.     the MDEF.
  119.  
  120.     */
  121.     
  122.     /*
  123.     
  124.     Set up the Color menu.
  125.     
  126.     The Color menu uses an 'Xmnu' resource to restore the Condense and Extend bits to their 
  127.     regular functions (as style bits), and sets the DEFAULT modifiers to Option-Command.
  128.     This means that key equivalents in this Menu need the Command and Option keys
  129.     held down, but all the style bits
  130.      are still free to be used as such. 
  131.     */
  132.     
  133.     prefs.optionKeyFlag = 0;
  134.     prefs.shiftKeyFlag = 0;
  135.     prefs.controlKeyFlag = 0;
  136.     prefs.cmdKeyFlag = 0;
  137.     prefs.isDynamicFlag = 0;
  138.     prefs.useCallbackFlag = 0;
  139.     prefs.forceNewGroupFlag = outline;
  140.     prefs.requiredModifiers = cmdKey + optionKey;
  141.  
  142.     MDEF_SetMenuPrefs(colorMenu, &prefs);
  143.     
  144.     
  145.     
  146.  
  147.     /*
  148.     
  149.     Set up the Modifiers menu.
  150.     
  151.     the Modifiers menu demonstrates all four modifier keys in action. Thus, we need
  152.     to use four style bits, which we select and store below.
  153.       
  154.     */
  155.     prefs.optionKeyFlag = underline;
  156.     prefs.shiftKeyFlag = extend;
  157.     prefs.cmdKeyFlag = bold;
  158.     prefs.controlKeyFlag = shadow;
  159.     prefs.isDynamicFlag = 0;
  160.     prefs.forceNewGroupFlag = 0;
  161.     prefs.useCallbackFlag = outline;
  162.     prefs.requiredModifiers = 0;
  163.  
  164.     MDEF_SetMenuPrefs(modifiersMenu, &prefs);
  165.     
  166.  
  167.  
  168.  
  169.     /*
  170.     
  171.     Set up the Callback menu.
  172.     
  173.     Note that we can make this call regardless of what MDEF we are using, 
  174.     because if an MDEF doesn't recognize a message (in our case, the 
  175.     SetCallback message), it simply ignores it.
  176.     
  177.     */
  178.  
  179.     prefs.optionKeyFlag = condense;
  180.     prefs.shiftKeyFlag = extend;
  181.     prefs.cmdKeyFlag = bold;
  182.     prefs.controlKeyFlag = 0;
  183.     prefs.isDynamicFlag = outline;
  184.     prefs.forceNewGroupFlag = italic;
  185.     prefs.useCallbackFlag = underline;
  186.     prefs.requiredModifiers = cmdKey;
  187.     
  188.     MDEF_SetCallbackProc(callbackMenu, (ProcPtr) &MyGetItemInfo);
  189.     MDEF_SetMenuPrefs(callbackMenu, &prefs);
  190.  
  191.  
  192.     DrawMenuBar();
  193.  
  194. }
  195. /* end SetUpMenus */
  196.  
  197. //#define    gestaltSystemVersion    'sysv'
  198. //#define svAllSmallData    0x0000FF00
  199. //#define    svAllLargeData    0x000000FF
  200.  
  201. // appends one Pascal string to another
  202. void AppendPStr(StringPtr destStr, StringPtr sourceStr);
  203. void AppendPStr(StringPtr destStr, StringPtr sourceStr)
  204. {
  205.     short    len = sourceStr[0];
  206.     short    curLen = destStr[0];
  207.  
  208.     BlockMove(&sourceStr[1],&destStr[curLen+1],len);
  209.     destStr[0] = curLen+len;
  210. }
  211.  
  212. // copies one Pascal string onto another
  213. void CopyPStr(StringPtr destStr, StringPtr sourceStr);
  214. void CopyPStr(StringPtr destStr, StringPtr sourceStr)
  215. {
  216.     short    len = sourceStr[0];
  217.  
  218.     BlockMove(&sourceStr[1],&destStr[1],len);
  219. }
  220.  
  221.  
  222. pascal    void MyGetItemInfo (short menuID, short previousModifiers, RichItemData *itemData)
  223.     /*
  224.     This routine is used by the Callback menu to demonstrate the
  225.     Mercutio callback mechanism. This routine is called for every
  226.     item in the menu flagged as a "callback item" (in our case,
  227.     with the Outline style bit).
  228.     
  229.     In this example, we check the Shift and Option keys to
  230.     determine what the text and icon of the menu item should
  231.     be.
  232.     
  233.     Note the "Dirty" parameter; if we don't change anything
  234.     in the menuItem, this parameter should be false to
  235.     avoid unnecessary redrawing (and flicker).
  236.     */
  237. {
  238.  
  239.      OSErr    theErr = noErr;
  240.     short    modifiers = 0;
  241.     long    currentTicks;
  242.     Str255    tickStr;
  243.     EventRecord    theEvent;
  244.     Boolean    temp;
  245.     
  246.     temp = EventAvail(everyEvent, &theEvent);
  247.     modifiers = theEvent.modifiers;
  248.  
  249.  
  250.     if (itemData->itemID == 37) {
  251.         switch (itemData->cbMsg)
  252.           {
  253.           case cbBasicDataOnlyMsg:              
  254.             if (modifiers & shiftKey) {
  255.                 itemData->flags = (itemData->flags | kShiftKey);
  256.                 if (modifiers, optionKey) {
  257.                     itemData->flags = itemData->flags | kOptionKey;
  258.                     CopyPStr(itemData->itemStr, "\pAdd Folders…");
  259.                 } else {
  260.                     CopyPStr(itemData->itemStr, "\pAdd Folder…");
  261.                 }
  262.             } else {
  263.                 if (modifiers & optionKey) {
  264.                     itemData->flags = itemData->flags | kOptionKey;
  265.                     CopyPStr(itemData->itemStr, "\pAdd Files…");
  266.                 } else {
  267.                     CopyPStr(itemData->itemStr, "\pAdd File…");
  268.                 }
  269.             
  270.             }
  271.               itemData->flags = itemData->flags | (kChangedByCallback & (modifiers != previousModifiers));
  272.               itemData->flags = itemData->flags | kHasIcon;
  273.               break;
  274.  
  275.           case    cbIconOnlyMsg:
  276.             if (modifiers & shiftKey) {
  277.                 if (modifiers, optionKey) {
  278.                     itemData->hIcon = (Handle) GetCIcon(addFoldersIconID);
  279.                 } else {
  280.                     itemData->hIcon = (Handle) GetCIcon(addFolderIconID);
  281.                 }
  282.             } else {
  283.                 if (modifiers, optionKey) {
  284.                     itemData->hIcon = (Handle) GetCIcon(addFilesIconID);
  285.                 } else {
  286.                     itemData->hIcon = (Handle) GetCIcon(addFileIconID);
  287.                 }
  288.             
  289.             }
  290.  
  291.               itemData->iconType = 'cicn';
  292.               itemData->flags = itemData->flags | kHasIcon;
  293.               
  294.             //    The item has changed if the user is holding down a new set of modifiers
  295.               itemData->flags = itemData->flags | (kChangedByCallback & (modifiers != previousModifiers));
  296.               
  297.             break;
  298.         
  299.           case    cbGetLongestItemMsg:
  300.             CopyPStr(itemData->itemStr, "\pAdd Folders…");
  301.               itemData->flags = itemData->flags | kShiftKey;
  302.               itemData->flags = itemData->flags | kOptionKey;
  303.             break;
  304.         
  305.           }
  306.     }
  307.     if (itemData->itemID == 38) {
  308.         switch (itemData->cbMsg)
  309.           {
  310.           case cbBasicDataOnlyMsg:
  311.               currentTicks = TickCount();
  312.               NumToString(currentTicks, tickStr);
  313.               CopyPStr(itemData->itemStr, "\pTicks: ");
  314.             AppendPStr(itemData->itemStr, tickStr);
  315.               itemData->flags = itemData->flags | kChangedByCallback;
  316.               break;
  317.  
  318.           case    cbIconOnlyMsg:
  319.             break;
  320.         
  321.           case    cbGetLongestItemMsg:
  322.               CopyPStr(itemData->itemStr, "\pTicks: 9999999999");
  323.             break;
  324.           }
  325.     }
  326.  
  327.  
  328.     
  329. }
  330.  
  331.  
  332.  
  333.  
  334. // int enable (MenuHandle menu, short item, short ok);
  335.  
  336.  
  337. /*****
  338.  * ToggleItem()
  339.  *
  340.  *    Turn the checkmark of a given item on or off.
  341.  *
  342.  *****/
  343.  
  344.  
  345. void ToggleItem (MenuHandle menu, short item);
  346. void ToggleItem (MenuHandle menu, short item)
  347. {
  348.     short    curMark;
  349.     
  350.     GetItemMark(menu, item, &curMark);
  351.     if (curMark == noMark)
  352.         CheckItem(menu, item, TRUE);
  353.     else
  354.         CheckItem(menu, item, FALSE);
  355. }
  356.  
  357.  
  358. /*****
  359.  * HandleMenu(mSelect)
  360.  *
  361.  *    Handle the menu selection. mSelect is what MenuSelect() and
  362.  *    MenuKey() return: the high word is the menu ID, the low word
  363.  *    is the menu item
  364.  *
  365.  *****/
  366.  
  367. void HandleMenu (long mSelect);
  368. void HandleMenu (long mSelect)
  369.  
  370. {
  371.     int            menuID = HiWord(mSelect);
  372.     int            menuItem = LoWord(mSelect);
  373.     short        dummy;
  374.     Str255        name;
  375.     GrafPtr        savePort;
  376.     DialogPtr    AboutDLOG;
  377.     DialogRecord AboutRecord;
  378.     
  379.     switch (menuID)
  380.       {
  381.       case    appleMenuID:
  382.         switch (menuItem)
  383.           {
  384.             case 1 :
  385.                 AboutDLOG = GetNewDialog(3000, &AboutRecord, (WindowPtr) (-1));
  386.                 ModalDialog(0L, &dummy);
  387.                 CloseDialog(AboutDLOG);
  388.                 break;
  389.             
  390.             default :
  391.                 GetPort(&savePort);
  392.                 GetItem(appleMenu, menuItem, name);
  393.                 OpenDeskAcc(name);
  394.                 SetPort(savePort);
  395.                 break;
  396.             }
  397.         break;
  398.         
  399.       case    fileMenuID:
  400.         switch (menuItem)
  401.           {
  402.           case popupDialogItem:
  403.           //    doPopupDialog(ourPopupMenu);
  404.               break;
  405.  
  406.           case    quitItem:
  407.             ExitToShell();
  408.             break;
  409.         
  410.           }
  411.         break;
  412.                   
  413.       case    editMenuID:
  414.         if (!SystemEdit(menuItem-1))
  415.           SysBeep(5);
  416.         break;
  417.         
  418.       case    modifiersMenuID:
  419.         ToggleItem (modifiersMenu, menuItem);
  420.         break;
  421.         
  422.       case    iconsMenuID:
  423.         ToggleItem (iconsMenu, menuItem);
  424.         break;
  425.         
  426.       case    nonPrintingMenuID:
  427.         ToggleItem (nonPrintingMenu, menuItem);
  428.         break;
  429.         
  430.       case    callbackMenuID:
  431.         ToggleItem (callbackMenu, menuItem);
  432.         break;
  433.         
  434.       case    colorMenuID:
  435.         ToggleItem (colorMenu, menuItem);
  436.         break;
  437.       }
  438. }
  439. /* end HandleMenu */
  440.  
  441.  
  442.  
  443.  
  444.  
  445. /****
  446.  * HandleEvent()
  447.  *
  448.  *        The main event dispatcher. This routine should be called
  449.  *        repeatedly (it  handles only one event).
  450.  *
  451.  *****/
  452.  
  453. void HandleEvent(void);
  454. void HandleEvent(void)
  455.  
  456. {
  457.     int    windowCode;
  458.     EventRecord    theEvent;
  459.     WindowPtr    theWindow;
  460.  
  461.     HiliteMenu(0);
  462.     SystemTask ();        /* Handle desk accessories */
  463.     
  464.     if (GetNextEvent (everyEvent, &theEvent))
  465.       switch (theEvent.what)
  466.         {
  467.         case mouseDown:
  468.             windowCode = FindWindow(theEvent.where, &theWindow);
  469.     
  470.             switch (windowCode)
  471.               {
  472.               case inSysWindow: 
  473.                 SystemClick (&theEvent, theWindow);
  474.                 break;
  475.         
  476.               case inMenuBar:
  477.                   HandleMenu(MenuSelect(theEvent.where));
  478.                 break;
  479.         
  480.               }
  481.               break;
  482.  
  483.             
  484.         case keyDown: 
  485.         case autoKey:
  486.             /*
  487.                 This codes is commented out in order to get the Modifiers menu
  488.                 to work (it doesn't require the commandKey to be held down.
  489.                 
  490.                 You may want to use a check like this in your code to speed
  491.                 up processing.
  492.             */
  493.             // if ((theEvent.modifiers & cmdKey) != 0)
  494.             //   {
  495.               HandleMenu(MDEF_MenuKey(theEvent.message,theEvent.modifiers,modifiersMenu));
  496.             //  }
  497.             break;
  498.                 
  499.         }
  500. }
  501. /* end HandleEvent */
  502.  
  503.  
  504.  
  505.  
  506.  
  507. /*****
  508.  * main()
  509.  *
  510.  *    This is where everything happens
  511.  *
  512.  *****/
  513.  
  514. main()
  515.  
  516. {
  517.  
  518.     StringHandle    theCopyright;
  519.     long    theVersion;
  520.     
  521.     InitMacintosh();
  522.     SetUpMenus();
  523.     
  524.     theCopyright = MDEF_GetCopyright(modifiersMenu);
  525.     theVersion = MDEF_GetVersion(modifiersMenu);
  526.     DisposeHandle ((Handle)theCopyright);
  527.     
  528.     for (;;)
  529.         HandleEvent();
  530.  
  531.     // we don't need to dispose of the menuHandles since we're quitting the application
  532.         
  533. }
  534.